package com.tsystems.school.jabber.DataBase.DAO;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;

import java.util.List;


public class GenericDAO<T> implements DAO<T>{
	protected Session session;
	protected Transaction tx;
	protected Class<T> type;

	public GenericDAO(Class<T> type){
		this.type = type;
	}

	public Long create(T newInstance) {
		Long result = null;
		try{
			startTransaction();
			result = (Long) session.save(newInstance);
			tx.commit();
		} catch (HibernateException he){
			handleHibernateException(he);
		}
		return result;
	}

	public T read(Long id) {
		T result = null;
		try{
			startTransaction();
			result = (T) session.get(type, id);
		} catch (HibernateException he){
			handleHibernateException(he);
		}
		return result;
	}

	public void update(T object) {
		try{
			startTransaction();
			session.update(object);
		} catch (HibernateException he){
			handleHibernateException(he);
		}
	}

	public void delete(T object) {
		try{
			startTransaction();
			session.delete(object);
		} catch (HibernateException he){
			handleHibernateException(he);
		}
	}

	public List<T> readAll(){
		List<T> result = null;
		try{
			startTransaction();
			result = findByCriteria();
		} catch (HibernateException he){
			handleHibernateException(he);
		}
		return result;
	}

	protected  List<T> findByCriteria(Criterion... criterionList){
		Criteria crit = session.createCriteria(type);
		for(Criterion c: criterionList){
			crit.add(c);
		}
		return crit.list();
	}

	protected void startTransaction(){
		session =  HibernateUtil.getSessionFactory().getCurrentSession();
		tx = session.beginTransaction();
	}

	protected void handleHibernateException(HibernateException he){
		tx.rollback();
		he.printStackTrace();
	}
}
